/***************************************************************************//**
 * @file MSc_XmlNode.cpp
 * @author  Marek M. Cel <marekcel@mscsim.org>
 *
 * @section LICENSE
 *
 * Copyright (C) 2014 Marek M. Cel
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/
#ifndef MSC_XML_NODE_CPP
#define MSC_XML_NODE_CPP
#endif

////////////////////////////////////////////////////////////////////////////////

#include <utils/MSc_XmlNode.h>

////////////////////////////////////////////////////////////////////////////////

MSc_XmlNode::MSc_XmlNode( xmlNodePtr node ) :
    m_node ( node )
{}

////////////////////////////////////////////////////////////////////////////////

std::string MSc_XmlNode::getAttribute( std::string name )
{
    if ( hasAttributes() )
    {
        xmlAttrPtr attr = m_node->properties;

        while ( attr != NULL )
        {
            if ( xmlStrcmp( attr->name, (const xmlChar*)name.c_str() ) == 0 )
            {
                if ( attr->children != NULL )
                {
                    xmlChar* value = xmlNodeListGetString( attr->children->doc, attr->children, 1);

                    std::string result( (const char*)value );

                    xmlFree( value );

                    return result;
                }
                else
                {
                    return std::string();
                }
            }

            attr = attr->next;
        }
    }

    return std::string();
}

////////////////////////////////////////////////////////////////////////////////

MSc_XmlNode::Attributes MSc_XmlNode::getAttributes()
{
    Attributes attributes;
    attributes.clear();

    if ( hasAttributes() )
    {
        xmlAttrPtr attr = m_node->properties;

        while ( attr != NULL )
        {
            if ( attr->children != NULL )
            {
                xmlChar* value = xmlNodeListGetString( attr->children->doc, attr->children, 1);

                std::string strName( (const char*)attr->name );
                std::string strValue( (const char*)value );

                attributes.insert( std::pair<std::string,std::string>( strName, strValue ) );

                xmlFree( value );
            }

            attr = attr->next;
        }
    }

    return attributes;
}

////////////////////////////////////////////////////////////////////////////////

MSc_XmlNode MSc_XmlNode::getFirstChild()
{
    MSc_XmlNode result;

    if ( isValid() )
    {
        if ( m_node->children != NULL )
        {
            result.m_node = m_node->children;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////

MSc_XmlNode MSc_XmlNode::getFirstChildElement( std::string name )
{
    MSc_XmlNode result;

    if ( isValid() )
    {
        xmlNodePtr child = m_node->children;

        while ( child != NULL )
        {
            if ( child->type == XML_ELEMENT_NODE )
            {
                if ( xmlStrcmp( child->name, (const xmlChar*)name.c_str() ) == 0 )
                {
                    result.m_node = child;

                    return result;
                }
            }

            child++;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////

MSc_XmlNode MSc_XmlNode::getNextSibling()
{
    MSc_XmlNode result;

    if ( isValid() )
    {
        if ( m_node->next != NULL )
        {
            result.m_node = m_node->next;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////

MSc_XmlNode MSc_XmlNode::getNextSiblingElement( std::string name )
{
    MSc_XmlNode result;

    if ( isValid() )
    {
        xmlNodePtr next = m_node->next;

        while ( next != NULL )
        {
            if ( next->type == XML_ELEMENT_NODE )
            {
                if ( xmlStrcmp( next->name, (const xmlChar*)name.c_str() ) == 0 )
                {
                    result.m_node = next;

                    return result;
                }
            }

            next = next->next;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////

std::string MSc_XmlNode::getText() const
{
    switch ( m_node->type )
    {
    case XML_TEXT_NODE:
        return std::string( (const char*)m_node->content );
        break;

    default:
        return std::string();
        break;
    }

    return std::string();
}
